//@version=6
indicator("RSI + Stochastic Combo (v6) — arrows + alerts (fixed labels)", overlay=true, max_labels_count=500)

// === INPUTS ===
groupRSI = "RSI Settings"
rsiLen     = input.int(14, "RSI Length", group=groupRSI)
rsiBuyLvl  = input.int(40, "RSI Buy Threshold", group=groupRSI)
rsiSellLvl = input.int(60, "RSI Sell Threshold", group=groupRSI)

groupStoch = "Stochastic Settings"
stochLen = input.int(14, "Stochastic %K Length", group=groupStoch)
smoothK  = input.int(3,  "Stochastic K Smoothing", group=groupStoch)
smoothD  = input.int(3,  "Stochastic D Smoothing", group=groupStoch)

groupDisplay = "Display"
showPriceLabels = input.bool(true, "Show price labels (BUY/SELL)", group=groupDisplay)
showArrows      = input.bool(true, "Show arrow shapes", group=groupDisplay)

// === CALCULATIONS ===
rsi = ta.rsi(close, rsiLen)

lowestLow   = ta.lowest(low, stochLen)
highestHigh = ta.highest(high, stochLen)
stochRange  = math.max(highestHigh - lowestLow, 1e-10)
rawK = (close - lowestLow) / stochRange * 100.0
k = ta.sma(rawK, smoothK)
d = ta.sma(k, smoothD)

// === SIGNAL LOGIC ===
// Arrow signals (exactly when arrows appear)
buySignal  = ta.crossover(k, d) and k < 20 and rsi < rsiBuyLvl
sellSignal = ta.crossunder(k, d) and k > 80 and rsi > rsiSellLvl

// === PLOTTING ARROWS ===
// plotshape must be in global scope; use boolean series to control visibility
plotshape(showArrows and buySignal,  title="BUY Signal",  location=location.belowbar, color=color.new(color.green,0),  style=shape.triangleup,   size=size.small)
plotshape(showArrows and sellSignal, title="SELL Signal", location=location.abovebar, color=color.new(color.red,0),    style=shape.triangledown, size=size.small)

// === SAFE LABEL HANDLING (avoid creating infinite labels) ===
var label lastBuyLabel  = na
var label lastSellLabel = na

if showPriceLabels
    if buySignal
        if not na(lastBuyLabel)
            label.delete(lastBuyLabel)
        // use named args in one call to avoid parser issues
        lastBuyLabel := label.new(x=bar_index, y=low, text="BUY", xloc=xloc.bar_index, yloc=yloc.price, style=label.style_label_up, color=color.new(color.green, 0), textcolor=color.white, size=size.tiny)
    if sellSignal
        if not na(lastSellLabel)
            label.delete(lastSellLabel)
        lastSellLabel := label.new(x=bar_index, y=high, text="SELL", xloc=xloc.bar_index, yloc=yloc.price, style=label.style_label_down, color=color.new(color.red, 0), textcolor=color.white, size=size.tiny)

// === ALERT CONDITIONS (only for arrows) ===
alertcondition(buySignal,  title="RSI+Stoch BUY",  message="BUY signal detected — RSI+Stochastic combo on {{ticker}} {{interval}}")
alertcondition(sellSignal, title="RSI+Stoch SELL", message="SELL signal detected — RSI+Stochastic combo on {{ticker}} {{interval}}")